home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xsok-1.000 / xsok-1 / xsok-1.01 / src / Xaw-main.c < prev    next >
C/C++ Source or Header  |  1995-10-14  |  12KB  |  374 lines

  1. /*****************************************************************************/
  2. /*                                         */
  3. /*                                         */
  4. /*    Xsok version 1.00 -- module Xaw-main.c                     */
  5. /*                                         */
  6. /*    main function for the Athena Widget interface.                 */
  7. /*    Written by Michael Bischoff (mbi@mo.math.nat.tu-bs.de)             */
  8. /*    November-1994                                 */
  9. /*    see COPYRIGHT.xsok for Copyright details                 */
  10. /*                                         */
  11. /*                                         */
  12. /*****************************************************************************/
  13. #include "X-sok.h"
  14. #include "Tableau.h"
  15. #include "version.h"
  16.  
  17. Widget toplevel;
  18.  
  19. static XtAppContext app_con;
  20. static void (*execfunc)(void) = NULL;
  21. static Widget messagebox, container, desktop;
  22. static Widget dialog, popup, paned;
  23. static Window mainwindow;
  24.  
  25.  
  26. void show_message(const char *str, ...) {
  27.     if (gamegraphic) {
  28.     static char last_message[256];
  29.     Arg Args;
  30.     va_list args;
  31.     va_start(args, str);
  32.     
  33.     if (!str) {
  34.         memset(last_message, ' ', sizeof(last_message)-1);
  35.         last_message[sizeof(last_message)-1] = '\0';
  36.     } else
  37.         vsprintf(last_message, str, args);
  38.     
  39.     XtSetArg(Args, XtNlabel, last_message);
  40.     XtSetValues(messagebox, &Args, 1);
  41.     }
  42. }
  43.  
  44. void SetTitle(void) {
  45.     if (XtWindow(toplevel)) {
  46.     static char windowname[48];
  47.     sprintf(windowname, "%s - Level %d", game.type, game.level);
  48.     /* printf("SetTitle(): toplevel = %p, window = %x\n",
  49.        toplev, XtWindow(toplevel)); */
  50.     XStoreName(dpy, XtWindow(toplevel), windowname);
  51.     }
  52. }
  53.  
  54. void cmd_LeaveSok(void) {
  55.     play_sound("goodbye");
  56.     XtDestroyApplicationContext(app_con);
  57.     exit(0);
  58. }
  59.  
  60. static void perform_command(Widget widget, XtPointer client_data, XtPointer call_data) {
  61.     (*(void (*)(void))client_data)();    /* any questions? */
  62. }
  63.  
  64. static void popup_confirm(const char *prompt) {
  65.     Arg args[2];
  66.     Position x, y;
  67.     Dimension xx, yy, wx, wy;
  68.  
  69.     XtSetArg(args[0], XtNlabel, prompt);
  70.     XtSetValues(dialog, args, 1);
  71.     XtVaGetValues(dialog,   XtNwidth, &xx, XtNheight, &yy, NULL);
  72.     XtVaGetValues(toplevel, XtNwidth, &wx, XtNheight, &wy, NULL);
  73.     x = (wx - xx)/2;
  74.     y = (wy - yy)/2;
  75.  
  76.     XtTranslateCoords(toplevel, x, y, &x, &y);
  77.     XtSetArg(args[0], XtNx, x);
  78.     XtSetArg(args[1], XtNy, y);
  79.     XtSetValues(popup, args, 2);
  80.     XtPopup(popup, XtGrabNone);
  81. }
  82.  
  83. void cmd_Confirm(void) {
  84.     if (execfunc) {
  85.     void (*execfunc2)(void) = execfunc;    /* erase it first! */
  86.     execfunc = NULL;
  87.     XtPopdown(popup);
  88.     (*execfunc2)();    /* finally execute the desired function */
  89.     }
  90. }
  91. void cmd_Cancel(void) {
  92.     if (execfunc) {
  93.     execfunc = NULL;
  94.     XtPopdown(popup);
  95.     }
  96. }
  97.  
  98. /* type converter functions: */
  99. static void mXtAP_Cancel (Widget w, XEvent *xev, String *params, Cardinal *num) { cmd_Cancel();  }
  100. static void mXtAP_Confirm(Widget w, XEvent *xev, String *params, Cardinal *num) { cmd_Confirm(); }
  101. static void Cancel(Widget widget, XtPointer client_data, XtPointer call_data)    { cmd_Cancel();  }
  102. static void Ok(Widget widget, XtPointer client_data, XtPointer call_data)    { cmd_Confirm(); }
  103.  
  104. void request_confirm(void (*dofunc)(void), const char *prompt) {
  105.     if (execfunc)
  106.     return;        /* request pending => deny another one */
  107.     if (game.finished || !game.n_moves) {
  108.     (*dofunc)();    /* perform action without confirmation */
  109.     return;
  110.     }
  111.     execfunc = dofunc;
  112.     popup_confirm(prompt);
  113. }
  114.  
  115. static String fallback_resources[] = { 
  116.     "*beNiceToColormap:            false",
  117.     "*shapeStyle:            Rectangle",
  118.     "*topShadowContrast:        20",
  119.     "*bottomShadowContrast:        40",
  120.     "*Scrollbar*background:        Grey70",
  121.     "*Background:            grey85",
  122.     "*Foreground:            black",
  123.     "*resizeToPreferred:        True",
  124.     "*input:                True",
  125.     "*showGrip:                off",
  126.     "*shadowWidth:                       2",
  127.     "*messages.justify:            Left",
  128.     "*upperbox.orientation:        XtorientHorizontal",
  129.     "*lowerbox.orientation:        XtorientHorizontal",
  130.     "*Tableau.backingStore:        WhenMapped",
  131.     "*Tableau.keyboardFile:        keys",
  132.     "*Tableau.messageFile:        messages",
  133.     "*Tableau.background:        black",
  134.     "*Tableau.rules:                Sokoban",
  135.     "*Viewport.allowHoriz:        False",        /* scrollbar disable! */
  136.     "*Viewport.allowVert:        False",        /* code is buggy! */
  137.     "*Viewport.forceBars:        False",
  138.     "*Viewport.useBottom:        True",
  139.     "*Viewport.useRight:        True",
  140.     "*Label.shadowWidth:        0",
  141.     "*Label.BorderWidth:        2",
  142.     "*Dialog*Translations: #override \n<Key>y: Ok()\n<Key>n: Cancel()\n",
  143.     "XSok*title:            XSok",
  144.     "XSok.prompt.allowShellResize:    True",
  145.     "XSok.prompt.saveUnder:        True",
  146.     "*Dialog*resizable:            True",
  147.     "*Hint.Translations: #override\n<BtnDown>:set()\n<BtnUp>:HintNotify()unset()\n",
  148.     "*Sound.state:            True",
  149.     "XSok.help.width:            403",
  150.     "XSok.help.height:            200",
  151.     "XSok.help.title:            XSok Help Window",
  152.     "XSok.help.saveUnder:        True",
  153.     "XSok*Close Help.fromHoriz:        Topic",
  154.     "*helptext*string:            Please choose a topic.",
  155.     "*helptext*displayCaret:        False",
  156.     "*helptext*scrollHorizontal:    whenNeeded",
  157.     "*helptext*scrollVertical:        whenNeeded",
  158.     "*helptext*editType:        read",
  159.     NULL,
  160. };
  161.  
  162. static XrmOptionDescRec options[] = {
  163.     /* tableau resources */
  164.     { "-rules",        "*Tableau.rules",    XrmoptionSepArg, NULL },
  165.     { "-level",        "*Tableau.level",    XrmoptionSepArg, NULL },
  166.     { "-username",    "*Tableau.username",    XrmoptionSepArg, NULL },
  167.     { "-xsokdir",    "*Tableau.xsokdir",    XrmoptionSepArg, NULL },
  168.     { "-xpmdir",    "*Tableau.xpmdir",    XrmoptionSepArg, NULL },
  169.     { "-savedir",    "*Tableau.savedir",    XrmoptionSepArg, NULL },
  170.     { "-messageFile",    "*Tableau.messageFile",    XrmoptionSepArg, NULL },
  171.     { "-keyboardFile",    "*Tableau.keyboardFile",XrmoptionSepArg, NULL },
  172.  
  173.     /* non-tableau resources */
  174. #ifdef SOUND
  175.     { "-sound",     "*Sound.state",          XrmoptionNoArg, (XtPointer)"True" },
  176.     { "-nosound",     "*Sound.state",          XrmoptionNoArg, (XtPointer)"False" },
  177. #endif
  178. };
  179.  
  180. static XtActionsRec moreActions[] = {
  181.     { "Cancel",        mXtAP_Cancel },
  182.     { "Ok",        mXtAP_Confirm }
  183. };
  184.  
  185. static void process_extra_args(int argc, char *argv[]) {
  186.     /* check extra args */
  187.     if (argc >= 2) {
  188.     fprintf(stderr, "xsok: invalid argument: %s\n", argv[1]);
  189.     fprintf(stderr, "usage: xsok [options]\n"
  190.         "options are all standard X11 toolkit options and\n"
  191.                 "-rules (ruleset)     to initially use specified rules\n"
  192.                 "-level (levelnr)     to set the startlevel\n"
  193.                 "-username (username) to set individual username for highscores\n"
  194.         "-xsokdir (dir)       to set the game directory\n"
  195.         "-xpmdir (dir)        to set the directory for xpm files\n"
  196.         "-savedir (dir)       to set the directory for saved games\n"
  197.         "-messageFile (file)  to set the message file name\n"
  198.         "-keyboardFile (file) define the keyboard assignment\n"
  199. #ifdef SOUND
  200.         "-sound               sound toggle on\n"
  201.         "-nosound             sound toggle off\n"
  202. #endif
  203.         );
  204.     exit(EXIT_FAILURE);
  205.     }
  206. }
  207.  
  208. const char *rulepool[16] = { "Xsok", "Sokoban", "Cyberbox", NULL };
  209.  
  210. static void selectrules(Widget w, XtPointer number, XtPointer garbage) {
  211.     const char *s = XtName(w);
  212.     /* printf("widget %s has been selected\n", s); */
  213.     change_rules(s);
  214.     NewLevel(1);
  215.     cmd_LevelInfo();
  216. }
  217.  
  218. #ifdef SOUND
  219. static Widget sound;
  220.  
  221. int checksound(void) {
  222.     Boolean retval;
  223.     Arg args[1];
  224.     XtSetArg(args[0], XtNstate, &retval);
  225.     XtGetValues(sound, args, 1);
  226.     return retval & 0xff;
  227. }
  228. #endif
  229.  
  230.  
  231. static void read_gametypes(void) {
  232.     char filename[256], s[80];
  233.     FILE *fp;
  234.     sprintf(filename, "%s/gametypes", xsokdir);
  235.     if ((fp = fopen(filename, "r"))) {
  236.     int i;
  237.     for (i = 3; i < 15; ++i) {
  238.         if (!fgets(s, sizeof(s), fp))
  239.         break;
  240.         if (*s == ';') {
  241.         --i;
  242.         continue;
  243.         }
  244.         if (strchr(s, '\n'))
  245.         *strchr(s, '\n') = '\0';
  246.         if (strlen(s) > 8)
  247.         s[8] = '\0';
  248.         rulepool[i] = strsav(s);
  249.     }
  250.     rulepool[i] = NULL;
  251.     fclose(fp);
  252.     } /* else keep default pool */
  253. }
  254.  
  255. int main(int argc, char *argv[]) {
  256.     Widget buttonpanel;
  257.     Widget gamebutton, gamemenu, rulesbutton, rulesmenu;
  258.     int i;
  259.     struct button {
  260.     const char *name; void (*func)(void);
  261.     } *bp;
  262.     static struct button buttons[] = {
  263.     { "Undo",          cmd_UndoMove },
  264.     { "Redo",          cmd_RedoMove },
  265.     { "Next Level",          cmd_NextLevel },
  266.     { "Score",          cmd_ShowScore },
  267. #ifdef ONLINE_HELP
  268.     { "Help",          popup_help },
  269. #endif
  270.     { "Save",          cmd_SaveGame },
  271.     { "Load",        cmd_LoadGame }
  272.     }, mbuttons[] = {
  273.     { "Drop Bookmark",    cmd_DropBookmark },
  274.     { "Goto Bookmark",    cmd_GotoBookmark },
  275.     { "Replay",        cmd_ReplayGame },
  276.     { "Restart",        cmd_RestartGame },
  277.      { "Next Level",        cmd_NextLevel },
  278.      { "Previous Level",    cmd_PrevLevel },
  279.     { "Quit",        rq_LeaveSok }
  280.     };
  281.  
  282.     /* use the command line arguments concerning the widgets */
  283.     switch_uid(1);
  284.     toplevel = XtAppInitialize(&app_con, "XSok", options, XtNumber(options),
  285.                    &argc, argv, fallback_resources, NULL, 0);
  286.     switch_uid(0);
  287.     process_extra_args(argc, argv);
  288.     XtAppAddActions(app_con, moreActions, XtNumber(moreActions));
  289.  
  290.     /* basic elements */
  291.     paned       = XtCreateManagedWidget("paned",    panedWidgetClass,    toplevel,      NULL, 0);
  292.     buttonpanel = XtCreateManagedWidget("buttonpanel",    boxWidgetClass,     paned,      NULL, 0);
  293.     messagebox = XtCreateManagedWidget("messages", labelWidgetClass, paned, NULL, 0);
  294.     show_message(TXT_WELCOME, VERSION);
  295.     graphics_control(Disable);
  296.  
  297.     container   = XtCreateManagedWidget("container",    viewportWidgetClass, paned,      NULL, 0);
  298.     desktop     = XtCreateManagedWidget("desktop",    tableauWidgetClass,  container,      NULL, 0);
  299.     /* XtAddCallback(container, XtNreportCallback, reportfunc, NULL); */
  300.  
  301.     /* create the button panel and its menus */
  302.     gamebutton  = XtCreateManagedWidget("Game", menuButtonWidgetClass, buttonpanel, NULL, 0);
  303.     gamemenu    = XtCreatePopupShell("gamemenu", simpleMenuWidgetClass, gamebutton, NULL, 0);
  304.     for (bp = mbuttons, i = 0; i < XtNumber(mbuttons); ++i) {
  305.     Widget w;
  306.     w = XtCreateManagedWidget(bp->name, smeBSBObjectClass, gamemenu, NULL, 0);
  307.     if (bp->func) XtAddCallback(w, XtNcallback, perform_command, bp->func);
  308.     ++bp;
  309.     }
  310.     XtVaSetValues(gamebutton, XtNmenuName, "gamemenu", NULL);
  311.  
  312.     /* create Rules button just right of the Game button */
  313.     rulesbutton = XtCreateManagedWidget("Level Subset", menuButtonWidgetClass, buttonpanel, NULL, 0);
  314.     rulesmenu   = XtCreatePopupShell("rulesmenu", simpleMenuWidgetClass, rulesbutton, NULL, 0);
  315.     XtVaSetValues(rulesbutton, XtNmenuName, "rulesmenu", NULL);
  316.  
  317.     /* rest of the buttons */
  318.     for (bp = buttons, i = 0; i < XtNumber(buttons); ++i) {
  319.     Widget w;
  320.     w = XtCreateManagedWidget(bp->name, commandWidgetClass, buttonpanel, NULL, 0);
  321.     if (bp->func) XtAddCallback(w, XtNcallback, perform_command, bp->func);
  322.     ++bp;
  323.     }
  324. #ifdef SOUND
  325.     sound = XtCreateManagedWidget("Sound", toggleWidgetClass, buttonpanel, NULL, 0);
  326. #endif
  327.  
  328.     /* OK. Now do the pop-up shells */
  329.     popup = XtCreatePopupShell("prompt", transientShellWidgetClass, toplevel, NULL, 0);
  330.     dialog = XtCreateManagedWidget("dialog", dialogWidgetClass, popup, NULL, 0);
  331.     XawDialogAddButton(dialog, "ok",     Ok,     (XtPointer)dialog);
  332.     XawDialogAddButton(dialog, "cancel", Cancel, (XtPointer)dialog);
  333.  
  334. #ifdef ONLINE_HELP
  335.     create_help();
  336. #endif
  337.     graphic.width = graphic.height = 0;
  338.     graphic.autolayout = 1;
  339.     XtRealizeWidget(toplevel);
  340.     XSync(dpy, 0);
  341.     mainwindow = XtWindow(toplevel);
  342.     XSetIconName(dpy, mainwindow, "xsok");
  343.     SetTitle();
  344.     table  = XtWindow(desktop);
  345.  
  346.     read_gametypes();
  347.     {   const char **rp;
  348.     for (rp = rulepool; *rp; ++rp) {
  349.         Widget w;
  350.         w = XtCreateManagedWidget(*rp, smeBSBObjectClass, rulesmenu, NULL, 0);
  351.         XtAddCallback(w, XtNcallback, selectrules, NULL);
  352.     }
  353.     }
  354.  
  355.     graphics_control(Enable);
  356.     XtRealizeWidget(popup);
  357.     XtAppMainLoop(app_con);    /* does not return */
  358.     return 0;            /* keep compiler happy */
  359. }
  360.  
  361. void Force_Resize(XSize_t w, XSize_t h) {
  362.     Arg args[1];
  363.     int hh;
  364.     Dimension hhh = 0;
  365.     XtSetArg(args[0], XtNheight, &hhh);
  366.     XtGetValues(paned, args, 1);
  367.     hh = hhh;        /* unsigned short => int */
  368.     XtGetValues(container, args, 1);
  369.     /* printf("rq %d, paned = %d, container = %d\n", h, hh, hhh); */
  370.     h += hh - hhh;    /* difference between overall size and Viewport size */
  371.  
  372.     XResizeWindow(dpy, mainwindow, w, h);
  373. }
  374.